{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 调用Ollama的Embedding模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "ResponseError",
     "evalue": "model \"bge-m3:latest\" not found, try pulling it first",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mResponseError\u001b[0m                             Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[1], line 14\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[38;5;66;03m# 测试代码\u001b[39;00m\n\u001b[0;32m     13\u001b[0m text \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m今晚月色很美\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m---> 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mdense_embedding_func\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124membedding\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m     15\u001b[0m dense_dim  \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlen\u001b[39m(dense_embedding_func(text)[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124membedding\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m     16\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdense向量维度：\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mdense_dim\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
      "Cell \u001b[1;32mIn[1], line 6\u001b[0m, in \u001b[0;36mdense_embedding_func\u001b[1;34m(text)\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdense_embedding_func\u001b[39m(text):\n\u001b[1;32m----> 6\u001b[0m     embeddings \u001b[38;5;241m=\u001b[39m \u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43membeddings\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m      7\u001b[0m \u001b[43m        \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mbge-m3:latest\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[0;32m      8\u001b[0m \u001b[43m        \u001b[49m\u001b[43mprompt\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtext\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m      9\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m     10\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m embeddings\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:379\u001b[0m, in \u001b[0;36mClient.embeddings\u001b[1;34m(self, model, prompt, options, keep_alive)\u001b[0m\n\u001b[0;32m    369\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21membeddings\u001b[39m(\n\u001b[0;32m    370\u001b[0m   \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m    371\u001b[0m   model: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    374\u001b[0m   keep_alive: Optional[Union[\u001b[38;5;28mfloat\u001b[39m, \u001b[38;5;28mstr\u001b[39m]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m    375\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m EmbeddingsResponse:\n\u001b[0;32m    376\u001b[0m \u001b[38;5;250m  \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m    377\u001b[0m \u001b[38;5;124;03m  Deprecated in favor of `embed`.\u001b[39;00m\n\u001b[0;32m    378\u001b[0m \u001b[38;5;124;03m  \"\"\"\u001b[39;00m\n\u001b[1;32m--> 379\u001b[0m   \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    380\u001b[0m \u001b[43m    \u001b[49m\u001b[43mEmbeddingsResponse\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    381\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mPOST\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    382\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m/api/embeddings\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    383\u001b[0m \u001b[43m    \u001b[49m\u001b[43mjson\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mEmbeddingsRequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    384\u001b[0m \u001b[43m      \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    385\u001b[0m \u001b[43m      \u001b[49m\u001b[43mprompt\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    386\u001b[0m \u001b[43m      \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    387\u001b[0m \u001b[43m      \u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mkeep_alive\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    388\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_dump\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexclude_none\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    389\u001b[0m \u001b[43m  \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:177\u001b[0m, in \u001b[0;36mClient._request\u001b[1;34m(self, cls, stream, *args, **kwargs)\u001b[0m\n\u001b[0;32m    173\u001b[0m         \u001b[38;5;28;01myield\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mpart)\n\u001b[0;32m    175\u001b[0m   \u001b[38;5;28;01mreturn\u001b[39;00m inner()\n\u001b[1;32m--> 177\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request_raw\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mjson())\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:122\u001b[0m, in \u001b[0;36mClient._request_raw\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m    120\u001b[0m   r\u001b[38;5;241m.\u001b[39mraise_for_status()\n\u001b[0;32m    121\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m httpx\u001b[38;5;241m.\u001b[39mHTTPStatusError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 122\u001b[0m   \u001b[38;5;28;01mraise\u001b[39;00m ResponseError(e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mtext, e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m    123\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m r\n",
      "\u001b[1;31mResponseError\u001b[0m: model \"bge-m3:latest\" not found, try pulling it first"
     ]
    }
   ],
   "source": [
    "import ollama\n",
    "\n",
    "client = ollama.Client(host='http://192.168.20.43:11434')\n",
    "\n",
    "def dense_embedding_func(text):\n",
    "    embeddings = client.embeddings(\n",
    "        model='bge-m3:latest', \n",
    "        prompt=text,\n",
    "        )\n",
    "    return embeddings\n",
    "\n",
    "# 测试代码\n",
    "text = '今晚月色很美'\n",
    "print(dense_embedding_func(text)['embedding'])\n",
    "dense_dim  = len(dense_embedding_func(text)['embedding'])\n",
    "print(f\"dense向量维度：{dense_dim}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 批量embedding\n",
    "\n",
    "调embed接口。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "ResponseError",
     "evalue": "model \"bge-m3:latest\" not found, try pulling it first",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mResponseError\u001b[0m                             Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[2], line 15\u001b[0m\n\u001b[0;32m      5\u001b[0m MODEL_NAME \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbge-m3:latest\u001b[39m\u001b[38;5;124m\"\u001b[39m \n\u001b[0;32m      7\u001b[0m docs \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m      8\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mArtificial intelligence was founded as an academic discipline in 1956.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m      9\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAlan Turing was the first person to conduct substantial research in AI.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m     10\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBorn in Maida Vale, London, Turing was raised in southern England.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m     11\u001b[0m ]\n\u001b[0;32m     13\u001b[0m vectors \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m     14\u001b[0m     vec\n\u001b[1;32m---> 15\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m vec \u001b[38;5;129;01min\u001b[39;00m \u001b[43mollama_client\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43membed\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mMODEL_NAME\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39membeddings\n\u001b[0;32m     16\u001b[0m ]\n\u001b[0;32m     18\u001b[0m \u001b[38;5;28mprint\u001b[39m(vectors)\n\u001b[0;32m     20\u001b[0m data \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m     21\u001b[0m     {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mid\u001b[39m\u001b[38;5;124m\"\u001b[39m: i, \n\u001b[0;32m     22\u001b[0m      \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mvector\u001b[39m\u001b[38;5;124m\"\u001b[39m: vectors[i], \n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m     26\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mlen\u001b[39m(docs))\n\u001b[0;32m     27\u001b[0m ]\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:356\u001b[0m, in \u001b[0;36mClient.embed\u001b[1;34m(self, model, input, truncate, options, keep_alive)\u001b[0m\n\u001b[0;32m    348\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21membed\u001b[39m(\n\u001b[0;32m    349\u001b[0m   \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m    350\u001b[0m   model: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    354\u001b[0m   keep_alive: Optional[Union[\u001b[38;5;28mfloat\u001b[39m, \u001b[38;5;28mstr\u001b[39m]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m    355\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m EmbedResponse:\n\u001b[1;32m--> 356\u001b[0m   \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    357\u001b[0m \u001b[43m    \u001b[49m\u001b[43mEmbedResponse\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    358\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mPOST\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    359\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m/api/embed\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    360\u001b[0m \u001b[43m    \u001b[49m\u001b[43mjson\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mEmbedRequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    361\u001b[0m \u001b[43m      \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    362\u001b[0m \u001b[43m      \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    363\u001b[0m \u001b[43m      \u001b[49m\u001b[43mtruncate\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtruncate\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    364\u001b[0m \u001b[43m      \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    365\u001b[0m \u001b[43m      \u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mkeep_alive\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    366\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_dump\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexclude_none\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    367\u001b[0m \u001b[43m  \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:177\u001b[0m, in \u001b[0;36mClient._request\u001b[1;34m(self, cls, stream, *args, **kwargs)\u001b[0m\n\u001b[0;32m    173\u001b[0m         \u001b[38;5;28;01myield\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mpart)\n\u001b[0;32m    175\u001b[0m   \u001b[38;5;28;01mreturn\u001b[39;00m inner()\n\u001b[1;32m--> 177\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request_raw\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mjson())\n",
      "File \u001b[1;32md:\\Python312\\Lib\\site-packages\\ollama\\_client.py:122\u001b[0m, in \u001b[0;36mClient._request_raw\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m    120\u001b[0m   r\u001b[38;5;241m.\u001b[39mraise_for_status()\n\u001b[0;32m    121\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m httpx\u001b[38;5;241m.\u001b[39mHTTPStatusError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 122\u001b[0m   \u001b[38;5;28;01mraise\u001b[39;00m ResponseError(e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mtext, e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m    123\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m r\n",
      "\u001b[1;31mResponseError\u001b[0m: model \"bge-m3:latest\" not found, try pulling it first"
     ]
    }
   ],
   "source": [
    "import ollama\n",
    "\n",
    "ollama_client = ollama.Client(host='http://192.168.20.43:11434')\n",
    "\n",
    "MODEL_NAME = \"bge-m3:latest\" \n",
    "\n",
    "docs = [\n",
    "    \"Artificial intelligence was founded as an academic discipline in 1956.\",\n",
    "    \"Alan Turing was the first person to conduct substantial research in AI.\",\n",
    "    \"Born in Maida Vale, London, Turing was raised in southern England.\",\n",
    "]\n",
    "\n",
    "vectors = [\n",
    "    vec\n",
    "    for vec in ollama_client.embed(input=docs, model=MODEL_NAME).embeddings\n",
    "]\n",
    "\n",
    "print(vectors)\n",
    "\n",
    "data = [\n",
    "    {\"id\": i, \n",
    "     \"vector\": vectors[i], \n",
    "     \"text\": docs[i], \n",
    "     \"subject\": \n",
    "     \"history\"}\n",
    "    for i in range(len(docs))\n",
    "]\n",
    "\n",
    "print(data)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
